package com.three.service;

import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.rocketmq.shade.com.alibaba.fastjson.JSON;
import com.alibaba.rocketmq.shade.com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.three.constant.Charset;
import com.three.constant.ShopConstants;
import com.three.domain.shop.PayLog;
import com.three.utils.LogUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Date;
import java.util.Map;

@Service
public class AlipayService {
    @Value("${pay.alipay.appId}")
    private String appId;
    @Value("${pay.alipay.url}")
    private String url;
    @Value("${pay.alipay.privateKey}")
    private String privateKey;
    @Value("${pay.alipay.publicKey}")
    private String publicKey;

    private AlipayClient alipayClient;

    @PostConstruct
    private void initAliPay() {
        alipayClient = new DefaultAlipayClient(
                url,
                appId,
                privateKey,
                "json",
                Charset.UTF8,
                publicKey,
                "RSA2");
    }

    /**
     * 0、签名验证
     * 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号
     * 2、判断total_amount是否确实为该订单的实际金额（即商户订单创建时的金额）
     * 3、校验通知中的seller_id（或者seller_email) 是否为out_trade_no这笔单据的对应的操作方（有的时候，一个商户可能有多个seller_id/seller_email）
     * 4、验证app_id是否为该商户本身
     * @return
     */
    public boolean check(Map<String, String> params) {
        try {
            return AlipaySignature.rsaCheckV1(
                    params,
                    publicKey,
                    Charset.UTF8,
                    "RSA2") && params.get("app_id").equals(appId);
        } catch (AlipayApiException e) {
            LogUtils.SHOP.error("阿里支付，验签失败，信息：{}", e);
            return false;
        }
    }

    /**
     * 处理阿里回调
     *
     * @param params
     * @return
     */
    public String handle(Map<String, String> params) {
        /**
         * 公共回传参数，如果请求时传递了该参数，则返回给商户时会在异步通知时将该参数原样返回。
         * 本参数必须进行UrlEncode之后才可以发送给支付宝
         * 将业务参数放在里面
         */
        String buss_params = "";
        try {
            buss_params = URLDecoder.decode(params.get("passback_params"), Charset.UTF8);
            if (StringUtils.isEmpty(buss_params)) {
                //业务参数不对
                return ShopConstants.FAILURE;
            }
            JSONObject buss_params_json = JSON.parseObject(buss_params);
            //构造订单
            PayLog order = PayLog.build(buss_params_json.getLong("playerId"), buss_params_json.getInteger("channelId"))
                    .setShopType(buss_params_json.getInteger("shopType"))//1、金币 2、钻石
                    .setItemName(buss_params_json.getString("itemName"))
                    .setItemPrice(buss_params_json.getInteger("itemPrice"))//金币和钻石的，都是人民币
                    .setPriceUnit(buss_params_json.getInteger("priceUnit"))
                    .setItemInfo(buss_params_json.getString("itemInfo"))
                    .setNumber(buss_params_json.getLong("number"))//数量
                    .setGift(buss_params_json.getInteger("gift"))//配置计算结果为整数
                    //支付宝参数
                    .setOrderCreateTime(new Date(params.get("gmt_create")))//创建订单
                    .setOrderEndTime(new Date(params.get("gmt_close")))//结束时间
                    .setTotalAmount(String.valueOf(params.get("total_amount")))//订单总金额
                    .setBuyerPayAmount(params.get("buyer_pay_amount"))// 玩家付款金额
                    .setBuyerLogonId(params.get("buyer_logon_id"))//玩家支付宝账号
                    .setBuyerId(params.get("buyer_id"))//玩家支付宝用户号
                    .setReceiptAmount(params.get("receipt_amount"))//商家实收金额
                    .setSellerEmail(params.get("seller_email"))//商家支付宝账号
                    .setSellerId(params.get("seller_id"))//商家支付宝用户号
                    .setTradeNo(params.get("trado_no"))//支付宝交易凭证——唯一
                    .setTradeStatus(params.get("trade_status"));//订单状态
            if (!order.check()) {
                return ShopConstants.FAILURE;
            }
            order.pay();
            order.receipt();
        } catch (UnsupportedEncodingException e) {
            LogUtils.SHOP.warn("阿里支付，业务编码不一致，信息：{}", e);
            return ShopConstants.FAILURE;
        }
        return ShopConstants.SUCCESS;
    }


}
